package com.example.a00;

import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import android.database.sqlite.SQLiteDatabase;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.math.BigInteger;
import java.text.BreakIterator;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import info.mqtt.android.service.Ack;
import info.mqtt.android.service.MqttAndroidClient;


//--------------------------------主函数-------------------------------------
public class MainActivity extends AppCompatActivity {

    private final String TAG = "AiotMqtt";
    /* 设备三元组信息 */
    final private String PRODUCTKEY = "k16xk8aneqk";
    final private String DEVICENAME = "mqtt_app";
    final private String DEVICESECRET = "299b9eb9bc01e4c751b52cdcd6436f7e";//MQTTX_Mon
    /* 自动Topic, 用于上报消息 */
    final private String PUB_TOPIC = "/" + PRODUCTKEY + "/" + DEVICENAME + "/user/update";
    /* 自动Topic, 用于接受消息 */
    final private String SUB_TOPIC = "/" + PRODUCTKEY + "/" + DEVICENAME + "/user/get";

    /* 阿里云Mqtt服务器域名 */
//    final String host = "tcp://" + PRODUCTKEY + ".iot-06z00e7d3f9s4cf.mqtt.iothub.aliyuncs.com:1883";
    final String host = "tcp://iot-06z00e7d3f9s4cf.mqtt.iothub.aliyuncs.com:1883";
    private String clientId;
    private String userName;
    private String passWord;
    MqttAndroidClient mqttAndroidClient;


    /*------------------------要运行的函数主体---------------------------------*/
    @SuppressLint("SuspiciousIndentation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        TextView subView = findViewById(R.id.textView);
        EditText Message_edit = findViewById(R.id.editText_send);

        deleteDatabase("users.db"); //需要删除旧的数据库时使用
        DBOpenHelper dbsqLiteOpenHelper = new DBOpenHelper(MainActivity.this,"users.db",null,1);
        SQLiteDatabase db = dbsqLiteOpenHelper.getWritableDatabase();


        /* 获取Mqtt建连信息clientId, username, password */
        AiotMqttOption aiotMqttOption = new AiotMqttOption().getMqttOption(PRODUCTKEY, DEVICENAME, DEVICESECRET);
        if (aiotMqttOption == null) {
            Log.e(TAG, "device info error");
        } else {
            clientId = aiotMqttOption.getClientId();
            userName = aiotMqttOption.getUsername();
            passWord = aiotMqttOption.getPassword();
        }


        /* 创建MqttConnectOptions对象并配置username和password */
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setUserName(userName);
        mqttConnectOptions.setPassword(passWord.toCharArray());

        /* 创建MqttAndroidClient对象, 并设置回调接口 */
        mqttAndroidClient = new MqttAndroidClient(getApplicationContext(),host,clientId, Ack.AUTO_ACK);

        /*连接阿里云平台*/
            mqttAndroidClient.connect(mqttConnectOptions,null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Log.i(TAG, "connect succeed");
                    subscribeTopic(SUB_TOPIC);
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Log.i(TAG, "connect failed:"+ exception.getMessage());
                    exception.printStackTrace();
                }
            });


        /*设置回调接口*/
        mqttAndroidClient.setCallback(new MqttCallback() {
            @Override
            public void connectionLost(Throwable cause) {
                Log.i(TAG, "connection lost");
            }


            @Override
            public void messageArrived(String topic, MqttMessage message) throws Exception {
                /* 通过View接收消息 */
                String message_get = new String(message.getPayload());
                Log.i(TAG, "topic: " + topic + ", msg: " + new String(message.getPayload()));

                try {
                    JSONObject jsonObject = new JSONObject(new String(message.getPayload()));
                    String userid = jsonObject.getString("id");
                    String _id = jsonObject.getString("zd_id");
                    String time = jsonObject.getString("datetime");
                    String temperature = jsonObject.getString("temperature");
                    String comgas = jsonObject.getString("comgas");
                    String flame = jsonObject.getString("flame");
                    String shake = jsonObject.getString("shake");
                    String light = jsonObject.getString("light");


                    ContentValues values = new ContentValues();
                    values.put("userid",userid);
                    values.put("_id",_id);
                    values.put("time",time);
                    values.put("temperature",temperature);
                    values.put("comgas",comgas);
                    values.put("flame",flame);
                    values.put("shake",shake);
                    values.put("light",light);

                    //数据库执行插入命令
                    db.insert("user", null, values);

                    subView.setText(message_get);

                }catch (JSONException e)
                {
                    e.printStackTrace();
                    Toast.makeText(MainActivity.this ,"数据解析异常！", Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken token) {
                Log.i(TAG, "msg delivered");
            }
        });



        /* 通过按键发布消息 */
        Button pubButton = findViewById(R.id.publish);
        pubButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                /* 输入消息文本 */
                String msg_edit = "\"{" + Message_edit.getText().toString() + "}\"";
                publishMessage(msg_edit);
            }
        });

        /* 跳转历史记录 */
        Button tohistoryButton = findViewById(R.id.display_sql);
        tohistoryButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent intent = new Intent(MainActivity.this,historyData.class);
               startActivity(intent);
            }
        });

        /* 跳转图表 */
        Button tolineButton = findViewById(R.id.tolinechart);
        tolineButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent intent = new Intent(MainActivity.this,mylinechart.class);
                startActivity(intent);
            }
        });



    }//这个括号别删了！！！！！



    //-------------------方法定义--------------------------

    public void subscribeTopic(String topic) {
            mqttAndroidClient.subscribe(topic, 0, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Log.i(TAG, "subscribed succeed");
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Log.i(TAG, "subscribed failed");
                    exception.printStackTrace();
                }
            });
        }


    /**
     * 向默认的主题/user/update发布消息
     * @param payload 消息载荷
     */
    public void publishMessage(String payload) {
            if (!mqttAndroidClient.isConnected()) {
                mqttAndroidClient.connect();
            }

            MqttMessage message = new MqttMessage();
            message.setPayload(payload.getBytes());
            message.setQos(0);
            mqttAndroidClient.publish(PUB_TOPIC, message,null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Log.i(TAG, "publish succeed!");
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Log.i(TAG, "publish failed!");
                    exception.printStackTrace();
                }
            });
    }

    /**
     * MQTT建连选项类，输入设备三元组productKey, deviceName和deviceSecret, 生成Mqtt建连参数clientId，username和password.
     */
    static class AiotMqttOption {
        private String username = "";
        private String password = "";
        private String clientId = "";

        public String getUsername() { return this.username;}
        public String getPassword() { return this.password;}
        public String getClientId() { return this.clientId;}

        /**
         * 获取Mqtt建连选项对象
         * @param productKey 产品秘钥
         * @param deviceName 设备名称
         * @param deviceSecret 设备机密
         * @return AiotMqttOption对象或者NULL
         */
        public AiotMqttOption getMqttOption(String productKey, String deviceName, String deviceSecret) {
            if (productKey == null || deviceName == null || deviceSecret == null) {
                return null;
            }

            try {
                String timestamp = Long.toString(System.currentTimeMillis());

                // clientId
                this.clientId = productKey + "." + deviceName + "|timestamp=" + timestamp +
                        ",_v=paho-android-1.0.0,securemode=2,signmethod=hmacsha256|";

                // userName
                this.username = deviceName + "&" + productKey;

                // password
                String macSrc = "clientId" + productKey + "." + deviceName + "deviceName" +
                        deviceName + "productKey" + productKey + "timestamp" + timestamp;
                String algorithm = "HmacSHA256";
                Mac mac = Mac.getInstance(algorithm);
                SecretKeySpec secretKeySpec = new SecretKeySpec(deviceSecret.getBytes(), algorithm);
                mac.init(secretKeySpec);
                byte[] macRes = mac.doFinal(macSrc.getBytes());
                password = String.format("%064x", new BigInteger(1, macRes));
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }

            return this;
        }
    }

}
